Kestrel-3

On TRIPOS vs. BOAR Project
Login

The Problem

The relatively recent and on-going legal actions between Cloanto and Hyperion Entertainment has me concerned about implementing VertigOS as a port of the BOAR Project. The BOAR Project is a clean-room implementation of a proper subset of AmigaOS. including only the exec.library and dos.library components of the operating system. While not binary compatible with AmigaOS, it should be source compatible with a large number of native AmigaDOS console applications, particularly those which treat BPTRs as opaque references. (BOAR implements all DOS pointers as APTRs instead of BPTRs.) BOAR's library and device driver APIs are sufficiently powerful to enable a significant reproduction of actual AmigaOS libraries (albeit disk-resident) that, frankly, has me concerned that I might become a future target for litigation.

I was around for the fall of Amiga, circa 2000, for what I like to call the Battle of the Operating Systems. You had AmigaDE, QNX Neutrino, MorphOS, AmigaOS Classic, and I think a few others which I can't remember. Lots of lawsuits, lots of uncertainty in the market, and lots of toxic partisanship in the public forums. Over the years, these have mostly subsided. And, had Cloanto not pressed charges against Hyperion recently, I wouldn't have thought twice about moving forward with porting the BOAR Project. The modernity of Cloanto's and Hyperion's actions, however, motivates my fear.

Requirements for a Replacement Basis

Ideally, the operating system for the Kestrel-3 should meet the following criteria:

Now let's look at some existing alternatives:

Pure Tripos: A Viable Work-Around?

Clearly, Tripos is clearly the closest thing to a sweet spot there is. That basically just leaves only the legal status of Tripos as my greatest unknown: I don't actually know the official legal status of Tripos. In fact, nobody actually seems to know anymore. However, I do know that many independent recreations of it has been made over the years. There's AROS, AmigaOS itself of course, MorphOS, and less Amiga-dependent, Cintpos. Wikipedia says that there is still commercial support for a now-Linux-hosted version of Tripos, but there is literally no details or supporting evidence to back this claim. I don't foresee problems by creating an independent and open source fork of Tripos.

For these reasons, I've decided to move VertigOS away from its AmigaOS underpinnings (via the BOAR Project) and towards unadulterated Tripos itself. I've not observed any commercial interest in Tripos since Metacomco owned the rights, and as well, Tripos' own inventor, Dr. Martin Richards, has invested some work in recreating Tripos to run hosted under a POSIX operating system. Ergo, with prior art for independent recreations existing, I feel much safer pursuing Tripos as a viable foundation for VertigOS than I do with AmigaOS.

Opportunities

Base Architecture and Easy Programming API

As it happens, this might end up being a better basis for the operating system anyway. According to the programmer's reference guide, the 68000 version of the Tripos kernel supports only 22 system calls. This is far smaller than even the most basic version of exec.library. The Tripos kernel is technically less capable than the AmigaOS kernel; however, in practical terms, they're still quite close to each other. Its calling convention is also simpler, dependent upon the 68K TRAP instruction instead of magic memory addresses and jump tables. For RISC-V purposes, we would use the ECALL instruction instead.

For the 68000 version of Tripos, the DOS library has nearly identical structure to exec-style libraries, and is called exactly the same way (right down to offsets being labeled with _LVO prefixes). I would not be surprised if there was some cross-pollination of ideas between exec and Tripos. Unlike exec libraries, however, there does not exist any kind of protocol for opening, closing, or expunging libraries. To gain access to the DOS library, a client would invoke the kernel call, FindDOS. The result (which always succeeds, so no need for error checking) is a pointer to the library base, from which you can make calls via LVOs. The following assembly listing sketches some RISC-V code that illustrates how VertigOS might be invoked on a Kestrel-3:

    ; Find our DOS library
    ;
    addi    a0,SC_FINDDOS
    ecall
    addi    s0,a0,0             ; Assign DOSBase to S0
    ;
    ; Open the RAM:Foo/Bar file
    ;
L1: auipc   s1,0                ; S1 -> L1
    ld      a0,Filename-L1(s1)  ; A0 -> filename
    addi    a1,x0,MODE_OLDFILE  ; A1 = open a hopefully existing file
    ld      t0,_LVOOpen(s0)     ; Invoke the Open call
    jalr    ra,0(t0)
    sd      a0,result1-L1(s1)   ; Save our result and dispatch if it worked
    bne     a0,x0,success
    ld      t0,_LVOIoErr(s0)    ; Otherwise, find out *why* our attempt failed
    jalr    ra,0(t0)
    sd      a0,result2-L1(s1)
    jal     x0,printErrorMsg    ; Print an error message, and exit.
    ; ...etc...

    align   8
Filename:
    dword   *+8
    byte    "RAM:Foo/Bar",0
result1:
    dword   0
result2:
    dword   0

This illustrates how one would call the kernel (via ecall) as well as how one would invoke the DOS API (via a call to an LVO).

It's not clear to me that I need to preserve these two calling conventions. Cintpos, Dr. Richards' most recent system, implements its kernel almost entirely in BCPL and uses the global vector to export its functionality. That is, the DOS and the kernel have uniform calling interfaces: the global vector. Still, I'll aim to keep the distinction as long as it doesn't become too onerous. Again, it's a proven architecture, and despite wanting to build a computer all my own, I'm not in the business of reinventing everything at once. ;-)

Shared Libraries

As I mentioned in my blog article on ELF, Tripos supported a kind of statically-compiled, shared library facility which shares a lot with Posix-style shared object libraries, but without all the janky complexity. AmigaDOS never supported this feature, but you better believe that a pure Tripos environment absolutely did, and I have full intentions of supporting this feature as well.

I intend on using this library mechanism to support a native graphical user interface, support networking, and include other facilities which I need in order to meet Ken's Challenge.

Memory Protection

Tripos, and indeed the first versions of VertigOS, will run in a single, flat, physical address space. OR, if not physical, then at least a single, flat, virtualized address space. Eventually, I'd like to try my hand at expanding its horizons and moving it into the multi-address space realm.

I have no defined plan for supporting this. However, I do know that a kernel which offers only 22 system calls and a DOS with only 32 system calls, will be vastly easier to adapt than a kernel with hundreds for each.

The existence of the FindDOS system call, ironically, just might be the ticket that makes the whole thing work.

I foresee the use-case where a program kicks off a new domain ("address space"), loads code into it, and starts it running as a background process. Alternatively, the operating system will allow a user to select which executables it trusts or doesn't trust, such that untrusted binaries are loaded/executed in their own domain. Since an application must call FindDOS to acquire a reference to the DOS API, this gives the kernel a chance to map whatever dependencies are required by the application into this new domain before the rest of the program has a chance to depend upon them.

IPC will always be a sticky point, of course; you can't use QPkt to send messages to different domains, for example. (Nearly all of Tripos messages have pointers baked into them, and the operation of QPkt depends heavily upon this fact.) However, if each address space basically gets its own private copy of Tripos, and if there exists a special handler to basically implement cross-domain sockets, normal calls to Read and Write would then be all you needed for full IPC between domains.